import { app, BrowserWindow, ipcMain, Menu } from "electron";
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
import { Result } from "./result";

export const defaultConfig = {
  id: 0, //唯一id
  title: "默认标题", //窗口标题
  width: 1280, //宽度
  height: 960, //高度
  minWidth: 800, //最小宽度
  minHeight: 600, //最小高度
  route: "", // 页面路由URL '/manage?id=123'
  resizable: true, //是否支持调整窗口大小
  minimizable: true, //是否最小化
  maximizable: true, //是否最大化
  backgroundColor: "#eee", //窗口背景色
  parentId: 0, //父窗口id( 等于0=使用main作为父窗口, 小于0=没有父窗口，其他搜索windows  )
};

/**
 * 窗口配置
 */
export class Window {
  constructor() {
    this.mainConfig = null; //
    this.configMap = {}; //窗口配置列表
    this.listen();
  }

  // 窗口配置
  buildWindowsOptions(config) {
    return {
      title: config.title,
      width: config.width,
      height: config.height,
      backgroundColor: config.backgroundColor,
      resizable: config.resizable,
      minimizable: config.minimizable,
      maximizable: config.maximizable,
      frame: true,
      show: true,
      webPreferences: {
        nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
        contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
      },
    };
  }

  getParent(id) {
    if (this.mainConfig) {
      if (id === 0) {
        return this.getWindow(this.mainConfig.id);
      } else if (id < 0) {
        return null;
      } else {
        return this.getWindow(id);
      }
    }
    return null;
  }

  getParentId(id) {
    if (this.mainConfig) {
      if (id === 0) {
        return this.mainConfig.id;
      } else if (id < 0) {
        return -1;
      } else {
        return id;
      }
    }
    return -1;
  }

  // 获取窗口
  getWindow(id) {
    return BrowserWindow.fromId(id);
  }

  // 获取全部窗口
  getAllWindows() {
    return BrowserWindow.getAllWindows();
  }

  buildWinUrl(route, winId) {
    if (process.env.WEBPACK_DEV_SERVER_URL) {
      let winURL = route
        ? `${process.env.WEBPACK_DEV_SERVER_URL}#${this.buildRouteInner(
            route,
            winId
          )}`
        : `${process.env.WEBPACK_DEV_SERVER_URL}`;
      console.log("dev:" + winURL);
      return winURL;
      // Load the url of the dev server if in development mode
      //win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
      //if (!process.env.IS_TEST) win.webContents.openDevTools();
    } else {
      createProtocol("app");
      let winURL = route
        ? `app://./index.html#${this.buildRouteInner(route, winId)}`
        : `app://./index.html`;
      // Load the index.html when not in development
      console.log("app:" + winURL);
      return winURL;
    }
  }

  buildRouteInner(route, winId) {
    if (route.search("\\u003F") == -1) {
      return `${route}?winId=${winId}`;
    } else {
      return `${route}&winId=${winId}`;
    }
  }

  // 创建窗口
  createWindows(params) {
    //console.log("------------开始创建窗口...");
    //console.log("params:");
    //console.log(params);
    Menu.setApplicationMenu(null);

    let config = Object.assign({}, defaultConfig, params);
    //console.log("config:");
    //console.log(config);

    let options = this.buildWindowsOptions(config);
    options.parent = this.getParent(config.parentId);
    //console.log("options:");
    //console.log(options);

    let win = new BrowserWindow(options);
    config.id = win.id;
    config.parentId = this.getParentId(config.parentId);

    if (this.mainConfig == null) {
      this.mainConfig = config;
    }

    this.configMap[win.id] = config;
    //console.log(this.configMap);

    if (config.maximize && config.resizable) {
      win.maximize();
    }

    win.on("close", () => {
      delete this.configMap[win.id];
      win.setOpacity(0);
    });

    win.loadURL(this.buildWinUrl(config.route, win.id));

    if (process.env.WEBPACK_DEV_SERVER_URL && !process.env.IS_TEST) {
      win.webContents.openDevTools();
    }

    win.once("ready-to-show", () => {
      win.show();
    });

    return config;
  }

  // 关闭所有窗口
  closeAllWindow() {
    for (let i in this.group) {
      if (this.group[i]) {
        if (this.getWindow(Number(i))) {
          this.getWindow(Number(i)).close();
        } else {
          //console.log("---------------------------");
          app.quit();
        }
      }
    }
  }

  success(r) {
    return JSON.stringify(Result.ok(r));
  }

  failure(reason) {
    return JSON.stringify(Result.error(-1, reason));
  }

  // 开启监听
  listen() {
    this.windowIpcMainInner();
    this.modulesIpcMainInner();
  }

  modulesIpcMainInner() {
    let modules = {};

    let ipcMappers = {};

    let files = require.context("./modules", false, /\.js$/);

    files.keys().forEach((key) => {
      modules[key.replace(/\.\/|\.js/g, "")] = files(key).default;
    });

    Object.keys(modules).forEach((key) => {
      Object.keys(modules[key]).forEach((mkey) => {
        let ikey = key + "." + mkey;

        ipcMappers[ikey] = modules[key][mkey];

        ipcMain.handle(ikey, async (event, json) => {
          let params = JSON.parse(json);
          try {
            var r = await ipcMappers[ikey](params);
            return this.success(r);
          } catch (err) {
            return this.failure(err.message);
          }
        });
      });
    });
    console.log(ipcMappers);
  }

  windowIpcMainInner() {
    // 关闭
    ipcMain.handle("window.closed", (event, json) => {
      let params = JSON.parse(json);
      //console.log("---------window.closed-------------");
      //console.log(params);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).close();
        if (this.group[Number(winId)]) delete this.group[Number(winId)];
      } else {
        this.closeAllWindow();
      }
      return this.success(true);
    });

    // 隐藏
    ipcMain.handle("window.hide", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).hide();
      } else {
        for (let i in this.configMap) {
          if (this.configMap[i]) this.getWindow(Number(i)).hide();
        }
      }
    });

    // 显示
    ipcMain.handle("window.show", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).show();
      } else {
        for (let i in this.configMap) {
          if (this.configMap[i]) this.getWindow(Number(i)).show();
        }
      }
      return this.success(true);
    });

    // 最小化
    ipcMain.on("window.mini", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).minimize();
      } else {
        for (let i in this.configMap) {
          if (this.configMap[i]) this.getWindow(Number(i)).minimize();
        }
      }
      return this.success(true);
    });

    // 最大化
    ipcMain.handle("window.max", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).maximize();
      } else {
        for (let i in this.configMap) {
          if (this.configMap[i]) this.getWindow(Number(i)).maximize();
        }
      }
      return this.success(true);
    });

    // 最大化/最小化
    ipcMain.on("window.max-min-size", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        if (this.getWindow(winId).isMaximized()) {
          this.getWindow(winId).unmaximize();
        } else {
          this.getWindow(winId).maximize();
        }
      }
      return this.success(true);
    });

    // 重新加载
    ipcMain.handle("window.reload", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).reload();
      } else {
        for (let i in this.configMap) {
          if (this.configMap[i]) this.getWindow(Number(i)).reload();
        }
      }
      return this.success(true);
    });

    // 创建窗口
    ipcMain.handle("window.create", (event, json) => {
      let params = JSON.parse(json);
      let options = params.options;
      let config = this.createWindows(options);
      return this.success(config);
    });

    // 信息
    ipcMain.handle("window.config", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      for (let i in this.configMap) {
        if (this.configMap[i].id == winId) {
          return this.success(this.configMap[i]);
        }
      }
      return this.failure("not found!!!");
    });

    ipcMain.handle("window.list", (event, json) => {
      let params = JSON.parse(json);
      let like = params.like;
      //console.log(this.configMap);
      // let list = this.configMap.filter((item) => {
      //   let n = item.title.search(like) != -1;
      //   return n;
      // });
      let list = [];
      for (let i in this.configMap) {
        if (this.configMap[i].title.search(like) != -1) {
          list.push(this.configMap[i]);
        }
      }
      return this.success(list);
    });

    ipcMain.on("window.send", (event, json) => {
      let params = JSON.parse(json);
      let winId = params.winId;
      if (winId) {
        this.getWindow(Number(winId)).webContents.send("window.recive", json);
      } else {
        for (let i in this.configMap) {
          if (this.configMap[i]) {
            this.getWindow(Number(i)).webContents.send("window.recive", json);
          }
        }
      }
    });
  }
}
